package com.emerquim.security;

import org.springframework.dao.DataAccessException;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.GrantedAuthorityImpl;
import org.springframework.security.userdetails.UserDetails;
import org.springframework.security.userdetails.UserDetailsService;
import org.springframework.security.userdetails.UsernameNotFoundException;

/**
 * Clase para implementar la funcionalidad de los servicios de la seguridad de spring
 * @author Felipe Criales
 */
public class UserDetailsServiceImpl implements UserDetailsService {

	/**
	 * El dao el cual perimte consultar a la base de datos el usuario
	 */
    private UserDao userDao;

    /**
     * Constructor de la clase
     * @param userDao Le llega el dao para la consulta del usuario
     */
    public UserDetailsServiceImpl(UserDao userDao) {
        this.userDao = userDao;
    }

    /**
     * Metodo para cargar un usuario dado su login
     * @param username El nombre del usuario
     */
    public UserDetails loadUserByUsername(String username)
            throws UsernameNotFoundException, DataAccessException {
        AppUser user = userDao.findUser(username);
        if (user == null)
            throw new UsernameNotFoundException("Usuario no encontrado: " + username);
        else {
            return makeUser(user);
        }
    }

    /**
     * Metodo para crear un usuario dado un login y un password
     * @param user El usuario
     * @return Retorna el detalle de un usuario con susu permisos
     */
    private org.springframework.security.userdetails.User makeUser(AppUser user) {
        return new org.springframework.security.userdetails.User(user.getLogin(), user
                .getPassword(), true, true, true, true,
                makeGrantedAuthorities(user));
    }

    /**
     * Crea los permisos del usuario segun sus roles
     * @param user El usuario con sus permisos
     */
    private GrantedAuthority[] makeGrantedAuthorities(AppUser user) {
        GrantedAuthority[] result = new GrantedAuthority[user.getRoles().size()];
        int i = 0;
        for (String role : user.getRoles()) {
            result[i++] = new GrantedAuthorityImpl(role);
        }
        return result;
    }
}
